package casia.isiteam.springbootshiro.controller.login;

import casia.isiteam.springbootshiro.model.po.common.UserInfo;
import casia.isiteam.springbootshiro.properties.other.ConfigurationItem;
import casia.isiteam.springbootshiro.properties.other.HttpState;
import casia.isiteam.springbootshiro.properties.result.HttpResult;
import casia.isiteam.springbootshiro.properties.shiro.ShiroPwdCustom;
import casia.isiteam.springbootshiro.service.user.UserInfoService;
import casia.isiteam.springbootshiro.util.IpUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.Serializable;
import java.util.Deque;
import java.util.LinkedList;

import static org.apache.shiro.web.filter.mgt.DefaultFilter.user;

/**
 * Author wzy
 * Date 2017/7/27 21:07
 */
@RestController
public class Login {
    private final static Logger logger = LoggerFactory.getLogger(Login.class);
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private ConfigurationItem config;

    @RequestMapping(value = "home",method={ RequestMethod.GET } )
    public Object home(HttpServletRequest request) throws Exception{
        return HttpResult.error( HttpState.HOME.code() ,HttpState.HOME.annotation() ,null );
    }
    @RequestMapping(value="/userlogout" ,method={RequestMethod.POST, RequestMethod.GET})
    public Object logout(RedirectAttributes redirectAttributes ){
        //使用权限管理工具进行用户的退出，跳出登录，给出提示信息
        SecurityUtils.getSubject().logout();
        redirectAttributes.addFlashAttribute("message", "您已安全退出");
        return HttpResult.sucess( redirectAttributes.getFlashAttributes());
    }
    /**
     * 登录
     * @param request
     * @param account
     * @param password
     * @return
     * @throws Exception
     */
    @ApiOperation(value="Login", notes="Login")
    @ApiImplicitParams({@ApiImplicitParam (name = "account", value = "账号", required = true, dataType = "String",paramType = "form"),
                        @ApiImplicitParam (name = "password", value = "密码", required = false, dataType = "String",paramType = "form")} )
    @RequestMapping(value = "userlogin",method={RequestMethod.POST})
    public Object login(HttpServletRequest request, HttpServletResponse response,String account, String password) throws Exception{
        if( StringUtils.isEmpty(account) || StringUtils.isEmpty(password) ){
            return HttpResult.error( HttpState.NOT_EMPTY.code(),HttpState.NOT_EMPTY.annotation() );
        }
        String logIp = IpUtil.LoginIP( request, account );
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token  = new UsernamePasswordToken(account, ShiroPwdCustom.encrypt(password) );

        try {
            subject.login(token);
            Session session = subject.getSession();
            session.setAttribute("subject",user);//放入会话信息
            session.setTimeout( config.sessionOutTime());
            UserInfo user = (UserInfo)subject.getPrincipal();
            if( config.isLoginIpSave() ){
                userInfoService.saveIp( logIp , user.getId() );
            }

            logger.info("用户[" + account + "]登录成功!");
            return HttpResult.sucess(user.getPermission().getFrame());
        }catch(UnknownAccountException uae){
            logger.info(HttpState.UNKNOWN_ACCOUNT.annotation(account));
            return   HttpResult.error(HttpState.UNKNOWN_ACCOUNT.code() , HttpState.UNKNOWN_ACCOUNT.annotation(account));
        }catch(IncorrectCredentialsException ice){
            logger.info(HttpState.PASSWORD_ERROR.annotation(account,ice.getMessage()));
            return   HttpResult.error(HttpState.PASSWORD_ERROR.code(), HttpState.PASSWORD_ERROR.annotation(account,"您还有"+ ice.getMessage()+"次机会! "));
        }catch(LockedAccountException lae){
            logger.info(HttpState.LOCKED_ACCOUNT.annotation(account));
            return   HttpResult.error(HttpState.LOCKED_ACCOUNT.code(), HttpState.LOCKED_ACCOUNT.annotation(account) );
        }catch(ExcessiveAttemptsException eae){
            logger.info(HttpState.EXCESSIVE_ATTEMPTS.annotation(account));
            return   HttpResult.error(HttpState.EXCESSIVE_ATTEMPTS.code(), HttpState.EXCESSIVE_ATTEMPTS.annotation(account) );
        }catch(DisabledAccountException sae){
            logger.info(HttpState.DISABLED_ACCOUNT.annotation(account));
            return   HttpResult.error(HttpState.DISABLED_ACCOUNT.code(), HttpState.DISABLED_ACCOUNT.annotation(account) );
        }catch(AuthenticationException ae){
            logger.info(HttpState.LOGIN_ERROR.annotation(account));
            return   HttpResult.error(HttpState.DISABLED_ACCOUNT.code(), HttpState.LOGIN_ERROR.annotation(account) );
        }
    }

}
